"""
事件总线 - 实现发布/订阅模式的事件系统
支持同步/异步事件处理、事件过滤、优先级处理等
"""

import asyncio
import inspect
import threading
import weakref
from typing import (
    Dict, List, Any, Optional, Callable, Union, Type, 
    Awaitable, TypeVar, Generic, Set
)
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import uuid
from collections import defaultdict, deque

from ..logging.manager import get_logger

T = TypeVar('T')

class EventPriority(Enum):
    """事件优先级"""
    LOW = 1
    NORMAL = 2
    HIGH = 3
    CRITICAL = 4

@dataclass
class Event:
    """基础事件类"""
    event_type: str
    data: Any = None
    timestamp: datetime = field(default_factory=datetime.utcnow)
    event_id: str = field(default_factory=lambda: str(uuid.uuid4()))
    source: Optional[str] = None
    priority: EventPriority = EventPriority.NORMAL
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def __post_init__(self):
        """事件创建后的初始化"""
        if not self.source:
            import inspect
            frame = inspect.currentframe()
            try:
                # 尝试获取调用者信息
                caller_frame = frame.f_back.f_back if frame and frame.f_back else None
                if caller_frame:
                    self.source = f"{caller_frame.f_code.co_filename}:{caller_frame.f_lineno}"
            finally:
                del frame

class IEventHandler(ABC):
    """事件处理器接口"""
    
    @abstractmethod
    async def handle(self, event: Event) -> Any:
        """处理事件"""
        pass
    
    @property
    def priority(self) -> EventPriority:
        """处理器优先级"""
        return EventPriority.NORMAL
    
    @property
    def event_types(self) -> List[str]:
        """支持的事件类型"""
        return []

# 为了兼容性，EventSubscriber是IEventHandler的别名
EventSubscriber = IEventHandler

@dataclass
class EventHandlerRegistration:
    """事件处理器注册信息"""
    handler: Union[Callable, IEventHandler]
    event_types: List[str]
    priority: EventPriority = EventPriority.NORMAL
    is_async: bool = False
    is_weak_ref: bool = False
    filter_func: Optional[Callable[[Event], bool]] = None
    max_calls: Optional[int] = None
    call_count: int = 0
    
    def matches_event(self, event: Event) -> bool:
        """检查是否匹配事件"""
        # 检查事件类型
        if self.event_types and event.event_type not in self.event_types:
            return False
        
        # 检查过滤条件
        if self.filter_func and not self.filter_func(event):
            return False
        
        # 检查调用次数限制
        if self.max_calls and self.call_count >= self.max_calls:
            return False
        
        return True

class EventBus:
    """事件总线"""
    
    def __init__(self, name: str = "default"):
        self.name = name
        self.logger = get_logger(f"eventbus.{name}")
        
        # 事件处理器注册表
        self._handlers: Dict[str, List[EventHandlerRegistration]] = defaultdict(list)
        self._global_handlers: List[EventHandlerRegistration] = []
        
        # 事件队列和处理
        self._event_queue: deque = deque()
        self._processing = False
        self._lock = threading.RLock()
        
        # 异步事件处理
        self._async_queue: Optional[asyncio.Queue] = None
        self._async_task: Optional[asyncio.Task] = None
        self._loop: Optional[asyncio.AbstractEventLoop] = None
        
        # 统计信息
        self._stats = {
            "events_published": 0,
            "events_processed": 0,
            "handlers_registered": 0,
            "errors": 0
        }
        
        # 事件历史（用于调试）
        self._event_history: deque = deque(maxlen=1000)
        self._enable_history = False
    
    def enable_history(self, enabled: bool = True):
        """启用/禁用事件历史记录"""
        self._enable_history = enabled
    
    def subscribe(
        self,
        event_types: Union[str, List[str]],
        handler: Union[Callable, IEventHandler],
        priority: EventPriority = EventPriority.NORMAL,
        filter_func: Optional[Callable[[Event], bool]] = None,
        max_calls: Optional[int] = None,
        weak_ref: bool = False
    ) -> str:
        """订阅事件"""
        if isinstance(event_types, str):
            event_types = [event_types]
        
        # 检测是否为异步处理器
        is_async = False
        if hasattr(handler, 'handle'):
            # IEventHandler 接口
            is_async = inspect.iscoroutinefunction(handler.handle)
        else:
            # 普通函数
            is_async = inspect.iscoroutinefunction(handler)
        
        registration = EventHandlerRegistration(
            handler=handler,
            event_types=event_types,
            priority=priority,
            is_async=is_async,
            is_weak_ref=weak_ref,
            filter_func=filter_func,
            max_calls=max_calls
        )
        
        with self._lock:
            for event_type in event_types:
                self._handlers[event_type].append(registration)
                # 按优先级排序
                self._handlers[event_type].sort(key=lambda x: x.priority.value, reverse=True)
            
            self._stats["handlers_registered"] += 1
        
        self.logger.info(
            f"Handler registered for events: {event_types}",
            handler=str(handler),
            priority=priority.name,
            is_async=is_async
        )
        
        return str(id(registration))
    
    def subscribe_global(
        self,
        handler: Union[Callable, IEventHandler],
        priority: EventPriority = EventPriority.NORMAL,
        filter_func: Optional[Callable[[Event], bool]] = None,
        max_calls: Optional[int] = None
    ) -> str:
        """订阅所有事件"""
        is_async = False
        if hasattr(handler, 'handle'):
            is_async = inspect.iscoroutinefunction(handler.handle)
        else:
            is_async = inspect.iscoroutinefunction(handler)
        
        registration = EventHandlerRegistration(
            handler=handler,
            event_types=[],  # 空列表表示全局
            priority=priority,
            is_async=is_async,
            filter_func=filter_func,
            max_calls=max_calls
        )
        
        with self._lock:
            self._global_handlers.append(registration)
            self._global_handlers.sort(key=lambda x: x.priority.value, reverse=True)
            self._stats["handlers_registered"] += 1
        
        self.logger.info(
            f"Global handler registered",
            handler=str(handler),
            priority=priority.name,
            is_async=is_async
        )
        
        return str(id(registration))
    
    def unsubscribe(self, registration_id: str) -> bool:
        """取消订阅"""
        with self._lock:
            # 在类型特定处理器中查找
            for event_type, handlers in self._handlers.items():
                for handler in handlers[:]:  # 创建副本进行迭代
                    if str(id(handler)) == registration_id:
                        handlers.remove(handler)
                        self._stats["handlers_registered"] -= 1
                        self.logger.info(f"Handler unsubscribed for {event_type}")
                        return True
            
            # 在全局处理器中查找
            for handler in self._global_handlers[:]:
                if str(id(handler)) == registration_id:
                    self._global_handlers.remove(handler)
                    self._stats["handlers_registered"] -= 1
                    self.logger.info("Global handler unsubscribed")
                    return True
        
        return False
    
    def publish(self, event: Union[Event, str], data: Any = None, **kwargs) -> None:
        """发布事件（同步）"""
        if isinstance(event, str):
            event = Event(event_type=event, data=data, **kwargs)
        
        with self._lock:
            self._stats["events_published"] += 1
            
            if self._enable_history:
                self._event_history.append(event)
        
        self.logger.info(
            f"Event published: {event.event_type} (id={event.event_id}, priority={event.priority.name}, source={event.source})"
        )
        
        # 同步处理事件
        self._process_event_sync(event)
    
    async def publish_async(self, event: Union[Event, str], data: Any = None, **kwargs) -> None:
        """发布事件（异步）"""
        if isinstance(event, str):
            event = Event(event_type=event, data=data, **kwargs)
        
        with self._lock:
            self._stats["events_published"] += 1
            
            if self._enable_history:
                self._event_history.append(event)
        
        self.logger.info(
            f"Event published async: {event.event_type} (id={event.event_id}, priority={event.priority.name}, source={event.source})"
        )
        
        # 异步处理事件
        await self._process_event_async(event)
    
    def _process_event_sync(self, event: Event):
        """同步处理事件"""
        handlers = self._get_matching_handlers(event)
        
        for registration in handlers:
            try:
                if registration.is_async:
                    # 跳过异步处理器
                    continue
                
                # 调用处理器
                if hasattr(registration.handler, 'handle'):
                    registration.handler.handle(event)
                else:
                    registration.handler(event)
                
                registration.call_count += 1
                self._stats["events_processed"] += 1
                
            except Exception as e:
                self._stats["errors"] += 1
                self.logger.error(
                    f"Error in event handler: {str(e)}",
                    event_type=event.event_type,
                    event_id=event.event_id,
                    handler=str(registration.handler),
                    exc_info=e
                )
    
    async def _process_event_async(self, event: Event):
        """异步处理事件"""
        handlers = self._get_matching_handlers(event)
        
        # 分别处理同步和异步处理器
        sync_handlers = [h for h in handlers if not h.is_async]
        async_handlers = [h for h in handlers if h.is_async]
        
        # 先处理同步处理器
        for registration in sync_handlers:
            try:
                if hasattr(registration.handler, 'handle'):
                    registration.handler.handle(event)
                else:
                    registration.handler(event)
                
                registration.call_count += 1
                self._stats["events_processed"] += 1
                
            except Exception as e:
                self._stats["errors"] += 1
                self.logger.error(
                    f"Error in sync event handler: {str(e)}",
                    event_type=event.event_type,
                    event_id=event.event_id,
                    handler=str(registration.handler),
                    exc_info=e
                )
        
        # 并发处理异步处理器
        if async_handlers:
            tasks = []
            for registration in async_handlers:
                task = self._handle_async_event(event, registration)
                tasks.append(task)
            
            await asyncio.gather(*tasks, return_exceptions=True)
    
    async def _handle_async_event(self, event: Event, registration: EventHandlerRegistration):
        """处理单个异步事件"""
        try:
            if hasattr(registration.handler, 'handle'):
                await registration.handler.handle(event)
            else:
                await registration.handler(event)
            
            registration.call_count += 1
            self._stats["events_processed"] += 1
            
        except Exception as e:
            self._stats["errors"] += 1
            self.logger.error(
                f"Error in async event handler: {str(e)}",
                event_type=event.event_type,
                event_id=event.event_id,
                handler=str(registration.handler),
                exc_info=e
            )
    
    def _get_matching_handlers(self, event: Event) -> List[EventHandlerRegistration]:
        """获取匹配的事件处理器"""
        handlers = []
        
        # 获取类型特定处理器
        with self._lock:
            for registration in self._handlers.get(event.event_type, []):
                if registration.matches_event(event):
                    handlers.append(registration)
            
            # 获取全局处理器
            for registration in self._global_handlers:
                if registration.matches_event(event):
                    handlers.append(registration)
        
        # 按优先级排序
        handlers.sort(key=lambda x: x.priority.value, reverse=True)
        
        return handlers
    
    def get_stats(self) -> Dict[str, Any]:
        """获取统计信息"""
        with self._lock:
            return {
                **self._stats,
                "active_handlers": sum(len(handlers) for handlers in self._handlers.values()) + len(self._global_handlers),
                "event_types": list(self._handlers.keys()),
                "history_size": len(self._event_history) if self._enable_history else 0
            }
    
    def get_history(self, limit: int = 100) -> List[Event]:
        """获取事件历史"""
        if not self._enable_history:
            return []
        
        with self._lock:
            return list(self._event_history)[-limit:]
    
    def get_handlers(self, event_type: str) -> List[EventHandlerRegistration]:
        """获取指定事件类型的处理器"""
        with self._lock:
            return self._handlers.get(event_type, []).copy()
    
    def clear_handlers(self):
        """清除所有处理器"""
        with self._lock:
            self._handlers.clear()
            self._global_handlers.clear()
            self._stats["handlers_registered"] = 0
        
        self.logger.info("All handlers cleared")
    
    def clear_history(self):
        """清除事件历史"""
        with self._lock:
            self._event_history.clear()
        
        self.logger.info("Event history cleared")

# 🚫 全局事件总线已完全移除
# 所有代码必须使用依赖注入模式获取事件总线实例

def get_event_bus(name: str = "default") -> EventBus:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 通过 RedFireContainer 获取事件总线：
       container = RedFireContainer.create_for_service("my_service", settings)
       bus = container.event_bus()
    
    2. 在服务构造函数中声明依赖：
       def __init__(self, event_bus: EventBus):
           self.event_bus = event_bus
    
    3. 在测试中使用独立实例：
       manager = EventBusManager()
       test_bus = manager.create_bus("test")
    """
    raise RuntimeError(
        "❌ get_event_bus() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Get from container: container.event_bus()\n"
        "  • Inject in constructor: def __init__(self, event_bus: EventBus)\n"
        "  • For tests: EventBusManager().create_bus('test')\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )

def publish(event: Union[Event, str], data: Any = None, **kwargs) -> None:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 在服务构造函数中注入事件总线：
       def __init__(self, event_bus: EventBus):
           self.event_bus = event_bus
    
    2. 使用注入的实例发布事件：
       self.event_bus.publish("user.created", {"user_id": user.id})
    """
    raise RuntimeError(
        "❌ Global publish() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Inject EventBus in constructor: def __init__(self, event_bus: EventBus)\n"
        "  • Use injected instance: self.event_bus.publish(event, data)\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )

async def publish_async(event: Union[Event, str], data: Any = None, **kwargs) -> None:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 在服务构造函数中注入事件总线：
       def __init__(self, event_bus: EventBus):
           self.event_bus = event_bus
    
    2. 使用注入的实例异步发布事件：
       await self.event_bus.publish_async("user.created", {"user_id": user.id})
    """
    raise RuntimeError(
        "❌ Global publish_async() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Inject EventBus in constructor: def __init__(self, event_bus: EventBus)\n"
        "  • Use injected instance: await self.event_bus.publish_async(event, data)\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )

def subscribe(
    event_types: Union[str, List[str]],
    handler: Union[Callable, IEventHandler],
    **kwargs
) -> str:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 在服务构造函数中注入事件总线：
       def __init__(self, event_bus: EventBus):
           self.event_bus = event_bus
    
    2. 使用注入的实例订阅事件：
       self.event_bus.subscribe("user.created", self.handle_user_created)
    """
    raise RuntimeError(
        "❌ Global subscribe() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Inject EventBus in constructor: def __init__(self, event_bus: EventBus)\n"
        "  • Use injected instance: self.event_bus.subscribe(event_types, handler)\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )

def unsubscribe(registration_id: str) -> bool:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 在服务构造函数中注入事件总线：
       def __init__(self, event_bus: EventBus):
           self.event_bus = event_bus
    
    2. 使用注入的实例取消订阅：
       self.event_bus.unsubscribe(registration_id)
    """
    raise RuntimeError(
        "❌ Global unsubscribe() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Inject EventBus in constructor: def __init__(self, event_bus: EventBus)\n"
        "  • Use injected instance: self.event_bus.unsubscribe(registration_id)\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )
